<?php
class Product_Service_ReceivingProccess
{
    protected $_receivingCode = null;
    protected $_receiving = array();
    protected $_receivingItem = array();
    protected $_error = null;
    protected $_userId = null;
    protected $_lastdate = null;
    protected $_verification = true; //开户验证数据事务

    public function __construct($array = null)
    {
        if ($array != null) {
            $this->setData($array);
        }
        $this->setUser();
        $this->_lastdate = date('Y-m-d H:i:s');
    }

    public function set($key, $value)
    {
        $this->$key = $value;
    }

    private function setUser()
    {
        if (empty($this->_userId) || $this->_userId == null) {
            $session = new Zend_Session_Namespace('userAuth');
            $this->_userId = isset($session->userID) ? $session->userID : 0;
        }
    }

    //整理数据
    private function setData($array = null)
    {
        if (!isset($array['order_qty']) || $array['order_qty'] == '') {
            $this->_error = '数据出错';
        }
        $receivingArr = array();
        $receivingRow = array();
        $i = 0;
        foreach ($array['orderQty'] as $key => $val) {
            //如果设置已到货
            if (isset($array['isReceive'][$key]) && $array['isReceive'][$key] == 1) {
                $i++;
                // $receivingArr[$i]['received_qty'] = 0; //$array['receiveQty'][$key];
                // $receivingArr[$i]['weight'] = $array['weight'][$key];
                // $receivingArr[$i]['param_non_labeled_qty'] = $array['nonLabelQty'][$key];
                // $receivingArr[$i]['param_received_qty'] = $array['receiveQty'][$key];
                // $receivingArr[$i]['remark'] = $array['remark'][$key];
                // $receivingArr[$i]['packaged'] = isset($array['isPacket'][$key]) ? 1 : 0; //是否带包装
                $receivingArr[$i]['ri_id'] = $key;
                $receivingArr[$i]['product_sku'] = $array['sku'][$key];
                $receivingArr[$i]['isReceive'] = isset($array['isReceive'][$key]) && $array['isReceive'][$key] == 1 ? 1 : 0; //是否到货 1:未到货

                $item = Product_Service_Receiving::getItemByItemId($key);
                $receivingArr[$i]['order_qty'] = isset($item['order_qty']) ? $item['order_qty'] : 0;
                $receivingArr[$i]['line_no'] = $i;
                $receivingArr[$i]['product_id'] = isset($item['product_id']) ? $item['product_id'] : '0';
                $receivingArr[$i]['is_qc'] = isset($item['is_qc']) ? $item['is_qc'] : 0;
                $receivingArr[$i]['status'] = isset($item['status']) ? $item['status'] : 0;
                $receivingArr[$i]['product_weight'] = isset($item['product']['product_weight']) ? $item['product']['product_weight'] : 0; //产品重量
                //推荐货架
                $receivingArr[$i]['ws_code'] = $this->getShelf($receivingArr[$i]['product_id'], 1);

                if (empty($this->_receivingCode)) {
                    $this->_receivingCode = isset($item['receiving_code']) ? $item['receiving_code'] : '';
                }
            }

        }
        $this->_receivingItem = $receivingArr;

        if (!empty($this->_receivingCode)) {
            $receivingRow = Product_Service_Receiving::getByReceivingCode($this->_receivingCode);
            if (!empty($receivingRow)) {
                $this->_receiving = $receivingRow;
                $this->_receiving['item'] = Product_Service_Receiving::getItems($this->_receivingCode);
            } else {
                $this->_error = 'AsnCode:' . $this->_receivingCode . '不存在.';
            }

        } else {
            $this->_error = 'AsnCode不能为空.';
        }

        unset($array, $receivingArr, $receivingRow);
    }

    /*
    * 验证
    */
    private function validation()
    {
        if (empty($this->_error)) {
            return array('ask' => 0, 'msg' => $this->_error);
        }

        if (count($this->_receivingItem) == 0) {
            return array('ask' => 0, 'msg' => '请选择已到货产品.');
        }

        if (empty($this->_receiving) || empty($this->_receivingItem)) {
            return array('ask' => 0, 'msg' => '数据异常.');
        }

        //目前还没有启用分批收货，提交时的Item长度必须一置
        if (count($this->_receivingItem) != count($this->_receiving['item'])) {
            return array('ask' => 0, 'msg' => '数据异常.Item条目数量不对,请重新提交.');
        }

        foreach ($this->_receivingItem as $key => $val) {
            if ($val['status'] > 0) {
                return array(
                    "ask" => 0,
                    "msg" => "SKU: " . $val['product_sku'] . " 已经完成收货,无法再次操作",
                );
            }
            //判断是否成功推荐货架号
            if (empty($val['ws_code'])) {
                return array(
                    "ask" => 0,
                    "msg" => "SKU: " . $val['product_sku'] . " 无法获取货架号.",
                );
            }
            if ($val['order_qty'] == 0) {
                return array(
                    "ask" => 0,
                    "msg" => "SKU: " . $val['product_sku'] . " 送货数量出现异常.",
                );
            }
        }
    }

    /*
    * 更新AsnItem
    */
    private function updateReceivingItem($options = array())
    {
        $obj = new Product_Model_ReceivingItem();
        $riId = $options['ri_id'];
        unset($options['ri_id']);
        $options['receivetime'] = $this->_lastdate;
        $options['modified_by'] = $this->_userId;
        $options['modified'] = $this->_lastdate;
        if (!$obj->update($options, $riId)) {
            throw new Exception('更新Item失败.' . $riId);
            return false;
        }
        return true;
    }

    /*
     * 占用推荐货架
     */
    private function useShelf($productId = null)
    {
        $date = $this->_lastdate;
        //推荐货架
        $defaultShelf = self::getRecommendShelf($productId);
        if (empty($defaultShelf)) {
            throw new Exception('获取推荐货架失败!' . $productId);
            return false;
        }

        //如果是新货架要占用
        $warehouseProducts = array();
        $wspRow = Warehouse_Service_Products::getByfield('ws_code', $defaultShelf, 1);
        $warehouseProductsLog = array(
            'ws_code' => $defaultShelf,
            'wpl_proc_type' => 1,
        );
        if (!empty($wspRow)) {
            if ($wspRow['wp_status'] == '0' && $wspRow['product_id'] == $productId) {
                $warehouseProducts['wp_status'] = 3;
            }
            if ($wspRow['wp_status'] == '0' && $wspRow['product_id'] != $productId) {
                $warehouseProducts['wp_status'] = 3;
                $warehouseProducts['product_id'] = $productId;
            }
            if (!Warehouse_Service_Products::update($warehouseProducts, $wspRow['wp_id'])) {
                throw new Exception("更新货架状态错误!" . $defaultShelf . ' ' . $productId);
                return false;
            }
            if (isset($warehouseProducts['wp_status']) && $warehouseProducts['wp_status'] != '') {
                $warehouseProductsLog['wpl_note'] = '收货推荐货架,更新状态.' . (isset($warehouseProducts['product_id']) ? ('product_id to ' . $warehouseProducts['product_id']) : '');
                $this->createWarehouseProductsLog($warehouseProductsLog);
            }

        } else {
            $addWarehouseProducts = array(
                'warehouse_id' => $this->_receiving['warehouse_id'],
                'customer_id' => $this->_receiving['customer_id'],
                'ws_code' => $defaultShelf,
                'product_id' => $productId,
                'wp_status' => 3, //占用
                'wp_quantity' => 0,
                'wh_create_date' => $date,
                'wh_last_update' => $date,
            );
            if (!Warehouse_Service_Products::add($addWarehouseProducts)) {
                throw new Exception("创建货架库存错误!" . $defaultShelf . ' ' . $productId);
                return false;
            }
            $warehouseProductsLog['wpl_note'] = '占用新货架,product_id to ' . $productId;
            $this->createWarehouseProductsLog($warehouseProductsLog);
        }
        return $defaultShelf;
    }

    /*
     * 根据产品ID及仓库ID,获取推荐货架号
     */
    public static function  getRecommendShelf($productId=1,$warehouseId=1){
        if (empty($productId)) {
            return false;
        }
        //库存是否有改产品 有:货架同已存放 无:据品类与分区绑定
        $defaultWsCode = '';
        $shelfData = array();
        $tmpshelf = array();
        $wsSort = 0;
        $warehouseProductRows = Warehouse_Service_Products::getByCond(array('product_id' => $productId, 'warehouse_id' => $warehouseId, '*', '', 0, 0));
        if (!empty($warehouseProductRows)) {
            foreach ($warehouseProductRows as $key => $val) {
                $shelfRows = Warehouse_Service_Shelf::getByfield('ws_code', $val['ws_code']);
                if (isset($shelfRows['ws_statu']) && $shelfRows['ws_statu'] == '1') {
                    $warehouseProductRows[$key]['ws_sort'] = $shelfRows['ws_sort'];
                    $wsSort = $shelfRows['ws_sort'];
                } else {
                    $warehouseProductRows[$key]['ws_sort'] = -1;
                    $wsSort = 0;
                }
                $shelfData[$wsSort - $key + ($val['wp_status'] == 1 ? 1 : 0)] = $warehouseProductRows[$key];
            }

            krsort($shelfData); //按优先级排序
            foreach ($shelfData as $key => $val) {
                if ($val['wp_status'] > 0) {
                    $defaultWsCode = $val['ws_code'];
                    return $defaultWsCode;
                }
            }

            //判断之前的货架,是否有其它产品使用
            foreach ($shelfData as $key => $val) {
                if ($val['wp_status'] == '0') {
                    $oldshelfRows = Warehouse_Service_Products::getByfield('ws_code', $val['ws_code'], 2);
                    foreach ($oldshelfRows as $wpk => $wpv) {
                        if ($wpv['product_id'] != $productId && $wpv['wp_status'] != '0') {
                            continue 2;
                        }
                    }
                    $defaultWsCode = $val['ws_code'];
                    return $defaultWsCode;
                }
            }

        } else {
            //查找上架数据,最后一个推荐的货架
            $putaway = array(
                'product_id' => $productId ,
                'putaway_status_in' => array('-1','0')
            );
            $putawayRows = Product_Service_Putaway::getByCondition($putaway, array('ws_code'), 1, 2);
            if(!empty($putawayRows)){
                return $putawayRows[0]['ws_code'];
            }

            //重新找一个新的空货架
            $productSer = new Product_Service_Product();
            $category = $productSer->getProductCategory($productId);
            //获取产品目录
            $waCodeAll=array();
            $wsCode=array();
            if(!empty($category)){
               $areaModel = new Warehouse_Model_Area();
               $areaRows= $areaModel->getByConditionAll(array('poc_id'=>array(0,$category['poc_id'])),array('poc_id','wa_code'),0,0);
               if(!empty($areaRows)){
                   foreach($areaRows as $val){
                       $waCodeAll[]=$val['wa_code'];
                       if($val['poc_id']==$category['poc_id']){
                           $waCode[]=$val['wa_code'];
                       }
                   }
               }
            }
            $condition = array(
                'wa_code'=>$waCodeAll ,
                'product_id' => $productId,
                'warehouse_id'=>1,
                'rand'=>1,//随机
                'recommend'=>1,//推荐货架
            );
            $pageSize = 20;
            $page = 1;
            $shelfRows = Warehouse_Service_Shelf::getByLeftJoinWarehouseProductsCondition($condition, array('warehouse_shelf.ws_code','warehouse_shelf.ws_statu','warehouse_shelf.ws_sort') , $pageSize, $page,array('warehouse_shelf.ws_sort desc', 'warehouse_shelf.ws_code asc', 'warehouse_shelf.ws_id'));
            if (!empty($shelfRows)) {
                while (count($shelfRows)) {
                    shuffle($shelfRows); //打乱排序
                    foreach ($shelfRows as $key => $val) {
                        $putaway = array(
                            'ws_code' => $val['ws_code'],
                            'putaway_status_in' => array('-1','0')
                        );
                        $putawayCount = Product_Service_Putaway::getByCondition($putaway, 'count(*)', 0, 0);
                        if ($putawayCount == 0) {
                            return $val['ws_code'];
                        }
                    }
                    unset($shelfRows);
                    $page++;
                    $shelfRows = Warehouse_Service_Shelf::getByLeftJoinWarehouseProductsCondition($condition, array('warehouse_shelf.ws_code','warehouse_shelf.ws_statu','warehouse_shelf.ws_sort') , $pageSize, $page,array('warehouse_shelf.ws_sort desc', 'warehouse_shelf.ws_code asc', 'warehouse_shelf.ws_id'));
                }
                return $defaultWsCode;
            }
        }
        return $defaultWsCode;
    }

    /*
     * 获取推荐货架号
     */
    private function getShelf($productId = '', $warehouseId = 1)
    {
        if (empty($productId)) {
            $this->_error = '获取推荐货架失败,产品不能为空!';
            return '';
        }
        //推荐货架
        $defaultShelf = self::getRecommendShelf($productId, $warehouseId);
        if (empty($defaultShelf)) {
            $this->_error = '获取推荐货架失败!Pid' . $productId . ' Wid' . $warehouseId;
            return '';
        }
        return $defaultShelf;
    }

    /*
    * 货架使用日志
    */
    private function createWarehouseProductsLog($array = array())
    {
        $warehouseProductsLog = array(
            'wpl_refId' => $this->_receivingCode,
            'user_id' => $this->_userId,
            'warehouse_id' => $this->_receiving['warehouse_id'],
            'wpl_add_time' => date('Y-m-d H:i:s'),
        );
        if (!empty($array)) {
            $warehouseProductsLog = array_merge($warehouseProductsLog, $array);
        }
        if (!Warehouse_Service_Products::CreateWarehouseProductsLog($warehouseProductsLog)) {
            throw new Exception('写入货架使用日志失败!');
            return false;
        }
        return true;
    }

    /*
     * 扣取标签费用
     */
    private function labelBalance($qty = 0)
    {
        if ($qty > 0) {
            $options = array(
                'cbhClass' => 0, //正常扣款
                'refCode' => $this->_receivingCode,
                'appType' => 8, //label扣款
                'cbhType' => '-1',
                'vale' => 0.1 * $qty,
                'currencyCode' => "USD",
                'note' => "产品无label，扣款"
            );
            $result = Customer_Service_CustomerBalance::procBalance($this->_receiving['customer_id'], $options);
            if (!$result) {
                throw new Exception('标签扣款失败!');
                return false;
            }
        }
        return true;
    }

    /*
     * 验证QC数据 并 更新ASN Order 状态
     * return ask 0=>处理失败,1=>验证通过 2.成功处理还原
     */
    private function validationAddDataTransaction()
    {
        $result = array(
            "ask" => 1,
            "msg" => '操作成功!!',
        );
        $WMProducts = new Warehouse_Model_Products();
        $dbAdapter = $WMProducts->getAdapter();
        $dbAdapter->beginTransaction();
        try {
            //重新设置
            $this->_receiving = Product_Service_Receiving::getByReceivingCode($this->_receivingCode);
            //更新ASN状态
            $AsnStatus = 3; //已收货
            $receiveitemnum = 0; //已收货item
            $receivingItems = Product_Service_Receiving::getItems($this->_receiving['receiving_code']);
            foreach ($receivingItems as $key => $value) {
                if ($value['status'] == 1 || $value['status'] == 0) $AsnStatus = 2;
                if ($value['status'] == 2) $receiveitemnum++;
            }
            //验证QC数据
            $qcitems = Product_Service_QualityControlOrder::getArrayByQcoRefCode($this->_receiving['receiving_code']);
            if (empty($qcitems) || $receiveitemnum != count($qcitems)) {
                //还原ASN
                $AsnStatus = 2; //ASN状态
                $this->restoreAsn();
                $result = array(
                    "ask" => 2,
                    "msg" => '数据异常,请刷新页面再重新提交收货!',
                );
            }

            //不是相同状态才更新
            if ($AsnStatus != $this->_receiving['status']) {
                $updateAsn = array(
                    'status' => $AsnStatus,
                    'modified_by' => $this->_userId,
                    'modified' => $this->_lastdate,
                );
                $receivingModel = new Product_Model_Receiving();
                if (!$receivingModel->update($updateAsn, $this->_receiving['receiving_code'])) {
                    $dbAdapter->rollback();
                    return array(
                        "ask" => 0,
                        "msg" => "ASN状态更新失败!2",
                    );
                }
            }

            $dbAdapter->commit();
            return $result;
        } catch (Exception $e) {
            $dbAdapter->rollback();
            return array(
                "ask" => 0,
                "msg" => $e->getMessage(),
            );
        }
    }

    /*
     * 还原Asn 删除QC及上架数据
     */
    private function restoreAsn()
    {
        $asnItemModel = new Product_Model_ReceivingItem();
        $putawayModel = new Product_Model_Putaway();
        foreach ($this->_receivingItem as $key => $val) {
            //更新Item 状态
            $options['status'] = 0;
            $options['receivetime'] = '0000-00-00 00:00:00';
            $options['modified_by'] = '0';
            $options['modified'] = $this->_lastdate;
            if (!$asnItemModel->update($options, $val['ri_id'])) {
                throw new Exception('更新Item失败.' . $val['ri_id']);
                return false;
            }
            //删除QC
            $qcItemRow = Product_Service_QualityControlItem::getByQcoCodeAndProductId($this->_receiving['receiving_code'], $val['product_id']);
            if (!empty($qcItemRow)) {
                if (!Product_Service_QualityControlOrder::deleteByQcoCode($qcItemRow['qco_code'])) {
                    throw new Exception('清理QC数据失败.' . $qcItemRow['qco_code']);
                    return false;
                }
            }
            //删除上架
            $condition = array(
                'receiving_code' => $this->_receiving['receiving_code'],
                'product_id' => $val['product_id']
            );
            $putawayRows = Product_Service_Putaway::getByCondition($condition, '*');
            if (!empty($putawayRows)) {
                foreach ($putawayRows as $pk => $putaway) {
                    if (!$putawayModel->delete($putaway['putaway_id'])) {
                        throw new Exception('清理上架数据失败.' . $putaway['putaway_id']);
                        return false;
                    }
                }
            }
        }
        return true;
    }

    /*
     * 收货事务
     * param array('ask'=>0,'msg'=>提示信息)
     */
    public function procReceiveTransaction()
    {
        //验证数据
        $result = $this->validation();

        if (isset($result['ask']) && $result['ask'] == 0) {
            $this->_verification = false;
            return $result;
        }

        $date = $this->_lastdate;
        $WMProducts = new Warehouse_Model_Products();
        $dbAdapter = $WMProducts->getAdapter();
        $dbAdapter->beginTransaction();
        try {

            //事务内,加强状态控制
            $receivingRow = Product_Service_Receiving::getByReceivingCode($this->_receivingCode);

            if (!in_array($receivingRow['status'], array('1', '2'))) {
                $dbAdapter->rollback();
                return array(
                    "ask" => 0,
                    "msg" => "状态异常,请确认是否已收货!",
                );
            }

            $noLabelQty = 0; //本次检查到无label总数量
            $isQcQty = 0;
            $qcoCodeArr = array();
            $putawayLotNumber = 1;
            foreach ($this->_receivingItem as $key => $val) {
                $qcoCode = Product_Service_QualityControlOrder::getCurdateLastCode();
                $qcoCodeArr[] = $qcoCode;
                if (!Product_Service_QualityControlOrder::getAddQcOrder($this->_receivingCode, $val['product_id'], $val['order_qty'], $qcoCode)) {
                    $dbAdapter->rollback();
                    return array(
                        "ask" => 0,
                        "msg" => "创建QC信息失败!" . $qcoCode . ' ' . $val['product_id'],
                    );
                }
                //更新ASN Item
                $updateRow = array(
                    'ri_id' => $val['ri_id'],
                    //'received_qty' => $val['received_qty'] + $val['current_received_qty'],
                    // 'packaged' => $val['packaged'],
                    // 'weight' => $val['weight'],
                    // 'remark' => $val['remark'],
                    'status' => 2,
                );

                if (!$this->updateReceivingItem($updateRow)) {
                    $dbAdapter->rollback();
                    return array('ask' => 0, 'msg' => '更新item数据错误!');
                }

                $putawayInsertRow = array(
                    'putaway_code' => Product_Service_Putaway::getCurdateLastCode(),
                    'putaway_type' => 1,
                    'receiving_code' => $this->_receiving['receiving_code'],
                    'warehouse_id' => $this->_receiving['warehouse_id'],
                    'product_id' => $val['product_id'],
                    'ws_code' => $val['ws_code'],
                    'putaway_lot_number' => $putawayLotNumber,
                    'putaway_quantity' => 0,
                    'putaway_note' => '' . $qcoCode . '',
                    'putaway_status' => -1,
                    'putaway_create_date' => $date,
                    'create_user_id' => $this->_userId);
                if (!Product_Service_Putaway::create($putawayInsertRow)) {
                    $dbAdapter->rollback();
                    return array(
                        "ask" => 0,
                        "msg" => "创建上架信息失败!",
                    );
                }
                $isQcQty += 1;
                //统计总数
                // $noLabelQty += $val['param_non_labeled_qty'];

            }

            //先取消无标签扣费 2012-08-23
            //$this->labelBalance($noLabelQty);

            //更新asn 状态  如果条目相同 直接更新为已收货
            if (count($this->_receivingItem) == count($this->_receiving['item'])) {
                $updateAsn = array(
                    'status' => 3,
                    'modified_by' => $this->_userId,
                    'modified' => $this->_lastdate,
                );
                $receivingModel = new Product_Model_Receiving();
                if (!$receivingModel->update($updateAsn, $this->_receiving['receiving_code'])) {
                    $dbAdapter->rollback();
                    return array(
                        "ask" => 0,
                        "msg" => "ASN状态更新失败!3",
                    );
                }
            }

            $dbAdapter->commit();
            return array(
                "ask" => 1,
                "msg" => '操作成功!',
            );
        } catch (Exception $e) {
            $dbAdapter->rollback();
            return array(
                "ask" => 0,
                "msg" => $e->getMessage(),
            );
        }
    }

    /*
     * 收货 主程序
     * 两个事务
     */
    public function procReceive()
    {
        $result = array(
            'ask' => 0,
            'msg' => '操作失败!'
        );
        $msg = array();
        $result = $this->procReceiveTransaction();
        $msg[] = $result['msg'];
        //以下事务是数据验证及还原ASN
        if ($this->_verification) {
            $result = $this->validationAddDataTransaction();
            $msg[] = $result['msg'] . '-1';
        }
        $result['result'] = array('receiving_code' => $this->_receiving['receiving_code'], 'lastdate' => $this->_lastdate, 'msg' => join('.', $msg));
        return $result;
    }

}